/**
 * 
 */
package ar.edu.utn.frsf.cidisi.ginet.generation.elementsestructure;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;

import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.ControlFlowSegment;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionPath;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocolElement;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Termination;

/**
 * @author Neri
 *
 */
public class TreeImpl implements TreeInterface {

	private EList<NodeStructure> nodes;
	
	public TreeImpl(InteractionProtocolElement node){
		this.nodes = new BasicEList<NodeStructure>();
		
		this.buildTree(this, node, null);
	}
	
	@Override
	public void addNode(InteractionProtocolElement node,
			InteractionPath parent) {
		int interactionPaths = 0;
		
		Map<InteractionPath, EList<InteractionProtocolElement>> childrens = new HashMap<InteractionPath, EList<InteractionProtocolElement>>();
		
		if(node instanceof ControlFlowSegment){
			EList<InteractionPath> interactionPathsList = ((ControlFlowSegment)node).getInteractionPath(); 
			for (InteractionPath interactionPath : interactionPathsList) {
				if(interactionPath.getElement().isEmpty()){
					childrens.put(interactionPath, null);
				}else{
					childrens.put(interactionPath, interactionPath.getElement());
				}
			}
		}

		NodeStructure nodeToAdd = new NodeStructure(parent, node, childrens, interactionPaths);
		
		this.nodes.add(nodeToAdd);		
	}

	/* (non-Javadoc)
	 * @see ar.edu.utn.frsf.cidisi.ginet.generation.elementsestructure.TreeInterface#getNode(ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocolElement)
	 */
	@Override
	public NodeStructure getNode(InteractionProtocolElement element) {
		for (NodeStructure node : this.nodes) {
			if(node.getNode().equals(element)){
				return node;
			}
		}
		return null;
	}


	@Override
	public NodeStructure getRoot() {
		for (NodeStructure node : this.nodes) {
			if(node.getParent() == null){
				return node;
			}
		}
		return null;
	}
	
	private void buildTree(TreeInterface tree, InteractionProtocolElement node, InteractionPath parent) {
		
		tree.addNode(node, parent);
		
		if(node instanceof ControlFlowSegment){			
			for (InteractionPath interactionPath : ((ControlFlowSegment)node).getInteractionPath()) {
				if(!interactionPath.getElement().isEmpty()){
					for (InteractionProtocolElement element : interactionPath.getElement()) {
						this.buildTree(tree, element, interactionPath);
					}
				}
			}	
		}
	
	}

	@Override
	public boolean hasTermination() {
		for (NodeStructure node : this.nodes) {
			if(node.getNode() instanceof Termination){
				return true;
			}
		}		
		return false;
	}
}
